﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;

namespace Common
{
    /// <summary>
    /// 枚举操作帮助类
    /// </summary>
    public class EnumHelper
    {
        #region ToDictionary

        /// <summary>
        /// <![CDATA[
        /// 将type类型的枚举 转换成 Dictionary<string, ValueType>
        /// ]]>
        /// </summary>
        /// <typeparam name="ValueType">枚举值数据类型</typeparam>
        /// <param name="type">枚举的原始类型</param>
        /// <param name="defaultName">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上加</param>
        /// <returns></returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举定义的类型
        ///     var dic = EnumHelper.ToDictionary<int>(typeof(EnumType),"=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static Dictionary<string, ValueType> ToDictionary<ValueType>(Type type, string defaultName = "", ValueType defaultValue = default(ValueType))
        {
            if (type == null)
            {
                throw new ArgumentException($"传入的枚举类型无效");
            }
            if (!type.IsEnum)
            {
                throw new ArgumentException($"类型{type.FullName} 不是有效的枚举类型");
            }
            Dictionary<string, ValueType> dic = new Dictionary<string, ValueType>();
            if (defaultName != string.Empty)
            {
                dic.Add(defaultName, defaultValue);
            }
            var array = Enum.GetValues(type);
            foreach (var item in array)
            {
                string itemName = item.ToString();
                ValueType itemValue = (ValueType)Convert.ChangeType(Convert.ToInt32(item), typeof(ValueType));
                dic.Add(itemName, itemValue);
            }
            return dic;
        }


        /// <summary>
        /// <![CDATA[
        /// 将枚举EnumType 转换成 Dictionary<string, ValueType>
        /// ]]>
        /// </summary>
        /// <typeparam name="EnumType">枚举名称</typeparam>
        /// <typeparam name="ValueType">枚举值数据类型</typeparam>
        /// <param name="defaultName">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上加</param>
        /// <returns>
        /// <![CDATA[  返回一个Dictionary<string, ValueType>对象 ]]>
        /// </returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举名称
        ///     var dic = EnumHelper.ToDictionary<EnumType,int>("=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static Dictionary<string, ValueType> ToDictionary<EnumType, ValueType>(string defaultName = "", ValueType defaultValue = default(ValueType))
        {
            return ToDictionary<ValueType>(typeof(EnumType), defaultName, defaultValue);
        }

        /// <summary>
        /// <![CDATA[
        /// 将枚举EnumType 转换成 Dictionary<string, int>
        /// ]]>
        /// </summary>
        /// <typeparam name="EnumType">枚举名称</typeparam>
        /// <param name="defaultName">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上加，默认为-1</param>
        /// <returns>
        /// <![CDATA[  返回一个Dictionary<string, int>对象 ]]>
        /// </returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举名称
        ///     var dic = EnumHelper.ToDictionary<EnumType>("=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static Dictionary<string, int> ToDictionary<EnumType>(string defaultName = "", int defaultValue = -1)
        {
            return ToDictionary<EnumType, int>(defaultName, defaultValue);
        }

        #endregion

        #region ToNameValues

        public static List<NameValue<string, ValueType>> ToNameValues<ValueType>(Type type, string defaultName = "", ValueType defaultValue = default(ValueType))
        {
            List<NameValue<string, ValueType>> list = new List<NameValue<string, ValueType>>();
            var dic = ToDictionary(type, defaultName, defaultValue);
            foreach (var item in dic.Keys)
            {
                NameValue<string, ValueType> model = NameValue.Instance(item, dic[item]);
                list.Add(model);
            }
            return list;
        }

        /// <summary>
        /// <![CDATA[
        /// 将枚举EnumType 转换成 List<NameValue<string, ValueType>>
        /// ]]>
        /// </summary>
        /// <typeparam name="EnumType">枚举名称</typeparam>
        /// <typeparam name="ValueType">枚举值数据类型</typeparam>
        /// <param name="defaultName">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上加</param>
        /// <returns>
        /// <![CDATA[  返回一个 List<NameValue<string, ValueType>> 对象 ]]>
        /// </returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举名称
        ///     var dic = EnumHelper.ToNameValues<EnumType,int>("=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static List<NameValue<string, ValueType>> ToNameValues<EnumType, ValueType>(string defaultName = "", ValueType defaultValue = default(ValueType))
        {
            return ToNameValues<ValueType>(typeof(EnumType), defaultName, defaultValue);
        }

        /// <summary>
        /// <![CDATA[
        /// 将枚举EnumType 转换成 List<NameValue<string, int>>
        /// ]]>
        /// </summary>
        /// <typeparam name="EnumType">枚举名称</typeparam>
        /// <param name="defaultName">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上加，默认为-1</param>
        /// <returns>
        /// <![CDATA[  返回一个 List<NameValue<string, int>> 对象 ]]>
        /// </returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举名称
        ///     var list = EnumHelper.ToNameValues<EnumType>("=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static List<NameValue<string, int>> ToNameValues<EnumType>(string defaultName = "", int defaultValue = -1)
        {
            return ToNameValues<EnumType, int>(defaultName, defaultValue);
        }

        #endregion

        #region ToTextValues

        public static List<TextValue<string, ValueType>> ToTextValues<ValueType>(Type type, string defaultText = "", ValueType defaultValue = default(ValueType))
        {
            List<TextValue<string, ValueType>> list = new List<TextValue<string, ValueType>>();
            var dic = ToDictionary(type, defaultText, defaultValue);
            foreach (var item in dic.Keys)
            {
                TextValue<string, ValueType> model = TextValue.Instance(item, dic[item]);
                list.Add(model);
            }
            return list;
        }


        /// <summary>
        /// <![CDATA[
        /// 将枚举EnumType 转换成 List<TextValue<string, ValueType>>
        /// ]]>
        /// </summary>
        /// <typeparam name="EnumType">枚举名称</typeparam>
        /// <typeparam name="ValueType">枚举值数据类型</typeparam>
        /// <param name="defaultText">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上加</param>
        /// <returns>
        /// <![CDATA[  返回一个 List<TextValue<string, ValueType>> 对象 ]]>
        /// </returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举名称
        ///     var list = EnumHelper.ToTextValues<EnumType,int>("=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static List<TextValue<string, ValueType>> ToTextValues<EnumType, ValueType>(string defaultText = "", ValueType defaultValue = default(ValueType))
        {
            return ToTextValues(typeof(EnumType), defaultText, defaultValue);
        }

        /// <summary>
        /// <![CDATA[
        /// 将枚举EnumType 转换成 List<TextValue<string, int>>
        /// ]]>
        /// </summary>
        /// <typeparam name="EnumType">枚举名称</typeparam>
        /// <param name="defaultText">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上，加默认为-1</param>
        /// <returns>
        /// <![CDATA[  返回一个 List<TextValue<string, int>> 对象 ]]>
        /// </returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举名称
        ///     var list = EnumHelper.ToTextValues<EnumType>("=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static List<TextValue<string, int>> ToTextValues<EnumType>(string defaultText = "", int defaultValue = -1)
        {
            return ToTextValues<EnumType, int>(defaultText, defaultValue);
        }

        #endregion

        #region ToKeyValues

        public static List<KeyValue<string, ValueType>> ToKeyValues<ValueType>(Type type, string defaultKey = "", ValueType defaultValue = default(ValueType))
        {
            List<KeyValue<string, ValueType>> list = new List<KeyValue<string, ValueType>>();
            var dic = ToDictionary(type, defaultKey, defaultValue);
            foreach (var item in dic.Keys)
            {
                KeyValue<string, ValueType> model = KeyValue.Instance(item, dic[item]);
                list.Add(model);
            }
            return list;
        }

        /// <summary>
        /// <![CDATA[
        /// 将枚举EnumType 转换成 List<KeyValue<string, ValueType>>
        /// ]]>
        /// </summary>
        /// <typeparam name="EnumType">枚举名称</typeparam>
        /// <typeparam name="ValueType">枚举值数据类型</typeparam>
        /// <param name="defaultKey">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上加</param>
        /// <returns>
        /// <![CDATA[  返回一个 List<KeyValue<string, ValueType>> 对象 ]]>
        /// </returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举名称
        ///     var list = EnumHelper.ToKeyValues<EnumType,int>("=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static List<KeyValue<string, ValueType>> ToKeyValues<EnumType, ValueType>(string defaultKey = "", ValueType defaultValue = default(ValueType))
        {
            return ToKeyValues(typeof(EnumType), defaultKey, defaultValue);
        }

        /// <summary>
        /// <![CDATA[
        /// 将枚举EnumType 转换成 List<KeyValue<string, int>>
        /// ]]>
        /// </summary>
        /// <typeparam name="EnumType">枚举名称</typeparam>
        /// <param name="defaultKey">第一项默认的名称，如空则不在原有基础上加</param>
        /// <param name="defaultValue">第一项默认的数值，如空则不在原有基础上加，加默认为-1</param>
        /// <returns>
        /// <![CDATA[  返回一个 List<KeyValue<string, int>> 对象 ]]>
        /// </returns>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// private void Test()
        /// {
        ///     //EnumType 为枚举名称
        ///     var list = EnumHelper.ToKeyValues<EnumType>("=全部=", 0);
        /// }
        /// ]]>
        /// </code>
        /// </example>
        public static List<KeyValue<string, int>> ToKeyValues<EnumType>(string defaultKey = "", int defaultValue = -1)
        {
            return ToKeyValues<EnumType, int>(defaultKey, defaultValue);
        }
        #endregion
    }

    class EnumHelperTest
    {
        public enum PayType
        {
            金币支付 = 1,
            现金支付 = 2,
            网银支付 = 3,
            支付宝支付 = 4,
            微信支付 = 5
        }

        public static void Test()
        {
            //ToDictionary Demo1
            var dic = EnumHelper.ToDictionary<PayType>();
            foreach (var key in dic.Keys)
            {
                Console.WriteLine(string.Format("Key={0}    Value={1}", key, dic[key]));
            }

            //ToDictionary Demo2
            var dic2 = EnumHelper.ToDictionary<PayType, string>(" 全部 ", "");
            foreach (var key in dic2.Keys)
            {
                Console.WriteLine(string.Format("Key={0}    Value={1}", key, dic2[key]));
            }
        }
    }
}
